home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 4
/
QRZ Ham Radio Callsign Database - Volume 4.iso
/
files
/
dsp
/
drbubtxt
/
toolstar.z
/
toolstar
/
tools
/
cldlod.hqx
/
cldlod.c
next >
Wrap
Text File
|
1992-02-21
|
18KB
|
937 lines
/* $Id: cldlod.c,v 1.20 92/02/14 15:55:24 tomc Exp $ */
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#if !defined ( macintosh )
#include <sys/types.h>
#endif
/* Headers for working with COFF files */
#include "coreaddr.h"
#include "maout.h"
#include "dspext.h"
/* function definitions */
static void onintr();
static void cld_to_lod();
static void read_headers();
static void read_strings();
static void start_record();
static void read_sections();
static void dump_data();
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
static void eprintf( FILE*, char*, ... );
static void error( char*, ... );
#else
static void eprintf();
static void error();
#endif
/* Global variables */
FILHDR file_header; /* File header structure */
AOUTHDR opt_header; /* Optional header structure */
OPTHDR link_header; /* Linker header structure */
int absolute; /* Absolute file flag */
long num_sections; /* Number of sections */
long section_seek; /* Used to seek to first section */
long symptr; /* File pointer to symbol table entries */
long num_symbols; /* Number of symbols */
int data_width; /* width of data for printing */
int addr_width; /* width of address for printing */
char *str_tab; /* Pointer to start of string char. array */
long str_length; /* Length in bytes of string array */
FILE *ifile = NULL; /* file pointer for input file */
char *ifn = NULL; /* pointer to input file name */
/* init is to non valid memory space */
int space = 777; /* 0=p, 1=x, 2=y, 3=l, 4=N */
main (argc, argv)
int argc;
char *argv[];
{
void exit ();
/* set up for signals, save program name, check for command line options */
signal (SIGINT, onintr);
/* check for correct command-line */
if ( argc != 2 )
{
fprintf( stderr, "usage: cldlod cldfile > lodfile\n" );
exit ( -1 );
}
if ( ( ifile = fopen( argv[1], "rb" ) ) == NULL )
error( "cannot open input file %s", argv[1] );
cld_to_lod();
fclose( ifile );
exit (0);
}
static void
cld_to_lod()
{
read_headers ();
read_strings ();
/* blow out the _START record */
if ( symptr != 0 && num_symbols != 0 ) /* no symbols */
start_record();
read_sections ();
if ( symptr != 0 && num_symbols != 0 ) /* no symbols */
dump_deb_symbols ();
/* blow out the _END record */
eprintf( stdout, "\n_END %01.*X\n", addr_width,
CORE_ADDR_ADDR (opt_header.entry) );
}
/* blow out the first .cmt symbol with:
n_sclass == C_NULL
n_type == T_NULL
*/
static void
start_record()
{
SYMENT se;
int i = 0, sym_id = -709;
if ( fseek( ifile, symptr, 0 ) != 0 )
error ("cannot seek to symbol table");
while ( i < num_symbols )
{
if ( freads( (char *)&se, sizeof (SYMENT), 1, ifile ) != 1 )
error ("cannot read symbol table entry %d", i);
#if !BIG_ENDIAN
if ( se.n_zeroes )
swapw( se.n_name, sizeof (long), 2 );
#endif
if ( strcmp( se.n_name, ".cmt" ) == 0 &&
se.n_sclass == C_NULL &&
se.n_type == T_NULL )
{
sym_id = CORE_ADDR_ADDR(se.n_value);
break;
}
i++;
}
/* */
eprintf( stdout, "_START " );
if ( sym_id >= 0 && str_length != 0 )
{
char *str_ptr = str_tab;
int len;
long offset = (long) sizeof( str_length );
do
{
if ( offset == sym_id )
break;
else
{
len = strlen( str_ptr );
offset += len + 1;
str_ptr += len + 1;
}
} while ( str_ptr < ( str_tab + str_length ) );
eprintf( stdout, "%s", str_ptr );
}
eprintf( stdout, "\n\n" );
}
static void
read_headers ()
{
if ( freads( (char *)&file_header, sizeof (FILHDR), 1, ifile ) != 1 )
error ("cannot read file header");
/* Save the global values */
num_sections = file_header.f_nscns;
num_symbols = file_header.f_nsyms;
symptr = file_header.f_symptr;
absolute = !!(file_header.f_flags & F_RELFLG);
/* check the MAGIC number */
if ( file_header.f_magic == M56KMAGIC )
{
data_width = 6;
addr_width = 4;
}
else if ( file_header.f_magic == M96KMAGIC )
{
data_width = addr_width = 8;
}
else if ( file_header.f_magic == M16KMAGIC )
{
data_width = addr_width = 4;
}
else
{
error( "Header has a bad magic number" );
}
/* optional header present */
if ( file_header.f_opthdr )
{
if ( absolute )
{
if ( freads( (char *)&opt_header,
(int)file_header.f_opthdr, 1, ifile ) != 1 )
error( "cannot read optional file header" );
}
else
{
if ( freads( (char *)&link_header,
(int)file_header.f_opthdr, 1, ifile ) != 1 )
error( "cannot read linker file header" );
}
}
/* File offset for first section headers */
section_seek = sizeof(FILHDR) + file_header.f_opthdr;
}
static void
read_strings ()
{
long strings;
strings = symptr + (num_symbols * SYMESZ);
if ( fseek( ifile, strings, 0 ) != 0 )
error ( "cannot seek to string table length" );
if ( freads( (char *)&str_length, 4, 1, ifile ) != 1 && !feof( ifile ))
error ( "cannot read string table length" );
if ( feof( ifile ))
str_length = 0L;
else if ( str_length )
{
str_length -= 4;
str_tab = (char *)malloc ((unsigned)str_length);
if ( fseek( ifile, strings + 4, 0 ) != 0 )
error( "cannot seek to string table" );
if (fread (str_tab, (int)str_length, 1, ifile) != 1)
error( "cannot read string table" );
}
}
static void
read_sections()
{
int i;
XCNHDR sh; /* Section header structure */
for (i = 0; i < num_sections; i++)
{
if (fseek (ifile, section_seek, 0) != 0)
error ("cannot seek to section headers");
if (freads ((char *)&sh, sizeof (XCNHDR), 1, ifile) != 1)
error ("cannot read section headers");
#if !BIG_ENDIAN
if (sh._n._s_n._s_zeroes)
swapw (sh._n._s_name, sizeof (long), 2);
#endif
section_seek += sizeof (XCNHDR);
dump_data (&sh);
}
}
char *
get_secname (sh)
XCNHDR *sh;
{
char *secname;
if ( sh->_n._s_n._s_zeroes )
secname = sh->_n._s_name;
else
{
if (sh->_n._s_n._s_offset < sizeof (str_length) ||
sh->_n._s_n._s_offset > str_length)
error ("invalid string table offset for section header name");
secname = &str_tab[sh->_n._s_n._s_offset - sizeof (str_length)];
}
return (secname);
}
static void
dump_data (sh)
XCNHDR *sh;
{
char *secname, *get_secname ();
long *raw_data;
int j;
if ( sh->_s.s_scnptr && sh->_s.s_size )
{
int memtype = CORE_ADDR_MAP( sh->_s.s_paddr );
int address = CORE_ADDR_ADDR( sh->_s.s_paddr );
char *mem_field;
secname = get_secname( sh );
/* determine the memory field (optional counter ok) */
switch ( memtype )
{
case memory_map_p:
mem_field = "P";
break;
case memory_map_pa:
mem_field = "PA";
break;
case memory_map_pb:
mem_field = "PB";
break;
case memory_map_pe:
mem_field = "PE";
break;
case memory_map_pi:
mem_field = "PI";
break;
case memory_map_pr:
mem_field = "PR";
break;
case memory_map_y:
mem_field = "Y";
break;
case memory_map_ya:
mem_field = "YA";
break;
case memory_map_yb:
mem_field = "YB";
break;
case memory_map_ye:
mem_field = "YE";
break;
case memory_map_yi:
mem_field = "YI";
break;
case memory_map_yr:
mem_field = "YR";
break;
case memory_map_x:
mem_field = "X";
break;
case memory_map_xa:
mem_field = "XA";
break;
case memory_map_xb:
mem_field = "XB";
break;
case memory_map_xe:
mem_field = "XE";
break;
case memory_map_xi:
mem_field = "XI";
break;
case memory_map_xr:
mem_field = "XR";
break;
case memory_map_l:
mem_field = "L";
break;
case memory_map_laa:
mem_field = "LAA";
break;
case memory_map_lab:
mem_field = "LAB";
break;
case memory_map_lba:
mem_field = "LBA";
break;
case memory_map_lbb:
mem_field = "LBB";
break;
case memory_map_le:
mem_field = "LE";
break;
case memory_map_li:
mem_field = "LI";
break;
default:
mem_field = "<ERROR>";
break;
}
raw_data = (long *)malloc((unsigned)(sh->_s.s_size * sizeof (long)));
if (fseek (ifile, sh->_s.s_scnptr, 0) != 0)
error ("cannot seek to raw data in section %s", secname);
if (freads ((char *)raw_data, (int)sh->_s.s_size,
sizeof (long), ifile) != sizeof (long))
error ("cannot read raw data in section %s", secname);
/* check for block data */
if ( sh->_s.s_flags & STYP_BLOCK )
{
if ( mem_field[0] == 'L' )
{
eprintf( stdout, "_BLOCKDATA X %01.*X %01.*X %01.*X\n",
addr_width, address,
addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
data_width, *raw_data++ );
eprintf( stdout, "_BLOCKDATA Y %01.*X %01.*X %01.*X\n",
addr_width, address,
addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
data_width, *raw_data++ );
}
else
{
eprintf( stdout, "_BLOCKDATA %s %01.*X %01.*X %01.*X\n",
mem_field,
addr_width, address,
addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
data_width, *raw_data++ );
}
}
else
{
eprintf (stdout, "_DATA %s %01.*X\n", mem_field,
addr_width, address );
j = 0;
while ( j < sh->_s.s_size )
{
if ( mem_field[0] == 'L' )
{
eprintf (stdout, "%01.*lX %01.*lX ",
data_width, *(raw_data+1),
data_width, *raw_data);
raw_data += 2;
j += 2;
}
else
{
eprintf (stdout, "%01.*lX ", data_width, *raw_data++);
j++;
}
if ( j % 8 == 0 && j < sh->_s.s_size )
eprintf (stdout, "\n");
}
eprintf (stdout, "\n");
}
}
}
dump_deb_symbols ()
{
SYMENT se;
AUXENT ae;
int i, j, k;
if (fseek (ifile, symptr, 0) != 0)
error ("cannot seek to symbol table");
i = 0;
while (i < num_symbols)
{
if (freads ((char *)&se, sizeof (SYMENT), 1, ifile) != 1)
error ("cannot read symbol table entry %d", i);
dump_se_d (&se); /* ek */
k = i++;
for (j = 0; j < se.n_numaux; j++)
{
if (freads ((char *)&ae, sizeof (AUXENT), 1, ifile) != 1)
error ("cannot read auxiliary entry %d for symbol entry %d", j, k);
i++;
}
}
}
dump_se_d (se) /* for debug symbol table */
SYMENT *se;
{
int old_space;
char *name, *type, *sclass;
char sym_type = 'I';
if (se->n_zeroes)
{
#if !BIG_ENDIAN
swapw (se->n_name, sizeof (long), 2);
#endif
name = se->n_name;
}
else
{
if (se->n_offset < sizeof (str_length) ||
se->n_offset > str_length)
error ("invalid string table offset for symbol table entry %d name", se - symptr);
name = &str_tab[se->n_offset - sizeof (str_length)];
}
if ( name[0] == '.' )
{
return;
}
switch ( se->n_sclass )
{
case C_EFCN:
sclass = "C_EFCN";
break;
case C_NULL:
sclass = "C_NULL";
break;
case C_AUTO:
sclass = "C_AUTO";
break;
case C_EXT:
sclass = "C_EXT";
break;
case C_STAT:
sclass = "C_STAT";
break;
case C_REG:
sclass = "C_REG";
break;
case C_EXTDEF:
sclass = "C_EXTDEF";
break;
case C_LABEL:
sclass = "C_LABEL";
break;
case C_ULABEL:
sclass = "C_REG";
break;
case C_MOS:
sclass = "C_MOS";
break;
case C_ARG:
sclass = "C_ARG";
break;
case C_STRTAG:
sclass = "C_STRTAG";
break;
case C_MOU:
sclass = "C_MOU";
break;
case C_UNTAG:
sclass = "C_UNTAG";
break;
case C_TPDEF:
sclass = "C_TPDEF";
break;
case C_USTATIC:
sclass = "C_USTATIC";
break;
case C_ENTAG:
sclass = "C_ENTAG";
break;
case C_MOE:
sclass = "C_MOE";
break;
case C_REGPARM:
sclass = "C_REGPARM";
break;
case C_FIELD:
sclass = "C_FIELD";
break;
case C_BLOCK:
sclass = "C_BLOCK";
break;
case C_FCN:
sclass = "C_FCN";
break;
case C_EOS:
sclass = "C_EOS";
break;
case C_FILE:
sclass = "C_FILE";
break;
case C_LINE:
sclass = "C_LINE";
break;
case C_ALIAS:
sclass = "C_HIDDEN";
break;
case C_HIDDEN:
sclass = "C_HIDDEN";
break;
default:
sclass = "<unknown>";
break;
}
switch ( BTYPE( se->n_type ) )
{
case T_NULL:
type = "T_NULL";
break;
case T_CHAR:
type = "T_CHAR";
break;
case T_SHORT:
type = "T_SHORT";
break;
case T_INT:
type = "T_INT";
break;
case T_LONG:
type = "T_LONG";
break;
case T_FLOAT:
type = "T_FLOAT";
sym_type = 'F';
break;
case T_DOUBLE:
type = "T_DOUBLE";
sym_type = 'F';
break;
case T_STRUCT:
type = "T_STRUCT";
break;
case T_UNION:
type = "T_UNION";
break;
case T_ENUM:
type = "T_ENUM";
break;
case T_MOE:
type = "T_MOE";
break;
case T_UCHAR:
type = "T_UCHAR";
break;
case T_USHORT:
type = "T_USHORT";
break;
case T_UINT:
type = "T_UINT";
break;
case T_ULONG:
type = "T_ULONG";
break;
default:
sclass = "<unknown>";
break;
}
old_space = space;
space = CORE_ADDR_MAP ( se->n_value );
switch ( space )
{
case memory_map_none:
if ( old_space != space ) eprintf( stdout, "_SYMBOL N\n" );
/* print symbol name and value */
eprintf (stdout, "%-19s %c %01.*lX\n", name, sym_type,
data_width, CORE_ADDR_ADDR (se->n_value));
break;
case memory_map_p:
/* print only pointers to functions (should be ext or stat...) */
if ( ISFCN (se->n_type) )
{
if ( old_space != space ) eprintf(stdout, "_SYMBOL P\n");
/* print symbol name and value */
eprintf (stdout, "%-19s I %01.*lX\n", name,
data_width, CORE_ADDR_ADDR (se->n_value));
}
else /* restore last written space */
space = old_space;
break;
case memory_map_x:
if (old_space != space) eprintf (stdout, "_SYMBOL X\n");
/* print symbol name and value */
eprintf (stdout, "%-19s %c %01.*lX\n", name, sym_type,
data_width, CORE_ADDR_ADDR (se->n_value));
break;
case memory_map_y:
if (old_space != space) eprintf (stdout, "_SYMBOL Y\n");
/* print symbol name and value */
eprintf (stdout, "%-19s %c %01.*lX\n", name, sym_type,
data_width, CORE_ADDR_ADDR (se->n_value));
break;
case memory_map_l:
if (old_space != space) eprintf (stdout, "_SYMBOL L\n");
/* print symbol name and value */
eprintf (stdout, "%-19s %c %01.*lX\n", name, sym_type,
data_width, CORE_ADDR_ADDR (se->n_value));
break;
default:
space = old_space; /* restore last written space */
return;
break;
}
}
/**
*
* name freads - swap bytes and read
*
* synopsis freads (ptr, size, nitems, stream)
* char *ptr; pointer to buffer
* int size; size of buffer
* int nitems; number of items to read
* FILE *stream; file pointer
*
* description Treats ptr as reference to union array; if necessary,
* swaps bytes to maintain base format byte ordering
* (big endian). Calls fread to do I/O.
*
**/
freads (ptr, size, nitems, stream)
char *ptr;
int size, nitems;
FILE *stream;
{
int rc;
rc = fread (ptr, size, nitems, stream);
#if !BIG_ENDIAN
swapw (ptr, size, nitems);
#endif
return (rc);
}
#if !BIG_ENDIAN
union wrd
{ /* word union for byte swapping */
unsigned long l;
unsigned char b[4];
};
/**
*
* name swapw - swap bytes in words
*
* synopsis swapw (ptr, size, nitems)
* char *ptr; pointer to buffer
* int size; size of buffer
* int nitems; number of items to write
*
* description Treats ptr as reference to union array; if necessary,
* swaps bytes to maintain base format byte ordering
* (big endian).
*
**/
swapw (ptr, size, nitems)
char *ptr;
int size, nitems;
{
union wrd *w;
union wrd *end = (union wrd *)ptr + ((size * nitems) / sizeof (union wrd));
unsigned i;
for (w = (union wrd *)ptr; w < end; w++)
{
i = w->b[0];
w->b[0] = w->b[3];
w->b[3] = i;
i = w->b[1];
w->b[1] = w->b[2];
w->b[2] = i;
}
}
#endif
static void
onintr () /* clean up from signal */
{
void exit ();
exit (1);
}
#ifdef va_dcl
#undef va_dcl
#define va_dcl char *va_alist;
#endif
/* VARARGS */
/* call fprintf, check for errors */
static void
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
eprintf (FILE *fp, char *fmt, ...)
#else
eprintf( va_alist )
va_dcl
#endif
{
void exit ();
va_list ap;
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
va_start (ap, fmt);
#else
FILE *fp;
char *fmt;
va_start (ap);
fp = va_arg (ap, FILE *);
fmt = va_arg (ap, char *);
#endif
if (vfprintf (fp, fmt, ap) < 0)
error ("cannot write to output file");
va_end (ap);
}
/* VARARGS */
static void
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
error (char *fmt, ...) /* display error on stderr, exit nonzero */
#else
error (va_alist) /* display error on stderr, exit nonzero */
va_dcl
#endif
{
void exit ();
va_list ap;
#if !LINT
int err = errno;
#endif
#if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
va_start (ap, fmt);
#else
char *fmt;
va_start (ap);
fmt = va_arg (ap, char *);
#endif
fprintf (stderr, "cldlod: ");
vfprintf (stderr, fmt, ap);
fprintf (stderr, "\n");
va_end (ap);
#if !LINT
if (err)
{
errno = err;
perror ( "cldlod" );
}
#endif
exit (1);
}